home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_400 / 406_01 / disked25 / source / dirent.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-01-14  |  13.7 KB  |  646 lines

  1. /***
  2. *dirent.c - disk directory maintenence
  3. *
  4. *Copyright (c) 1993-1994, Gregg Jennings.  All wrongs reserved.
  5. *   P O Box 200, Falmouth, MA 02541-0200
  6. *
  7. *Purpose:
  8. *   Handles the displaying and editing of directory sectors for DISKED.C.
  9. *
  10. *Notice:
  11. *   This progam may be freely used and distributed.  Any distrubution
  12. *   with modifications must retain the above copyright statement and
  13. *   modifications noted.
  14. *   No pulp-publication, in whole or in part, permitted without
  15. *   permission (magazines or books).
  16. *******************************************************************************/
  17.  
  18. /*
  19.    Versions:
  20.  
  21.    1.2   14-Jan-1994    =0 bug fix in changedir()
  22.    1.1   13-Nov-1993    Started structures
  23.    1.0   June 1993
  24.  
  25.    Release Notes:
  26.  
  27.    This is all "Brute Force" code.  Written in a couple a days after
  28.    I wanted to arange all my directories is a certain non-sorted way
  29.    easier than a touch program.
  30. */
  31.  
  32. #include <stdio.h>
  33. #include <conio.h>
  34. #include <ctype.h>
  35.  
  36. #include "mylib.h"
  37. #include "keys.h"
  38. #include "dirent.h"
  39.  
  40. #define isexten(c) ( (c>0x7f) && (c<255) )
  41.  
  42. static int attrib(unsigned char *b);
  43. static int text(int len, unsigned char *b);
  44. static int dostime(unsigned int time, unsigned int *t);
  45. static int dosdate(unsigned int date, unsigned int *d);
  46. static int command(int c);
  47. static int pdirent(unsigned char *buf);
  48. static void distime(DosTime *dt);
  49. static void disdate(DosDate *dd);
  50.  
  51. /* ...filename.txt...ttri...hh:mm:ss...mm/dd/yy...1234567...1234567 */
  52. static char
  53. *dir_header="   File           Attr   Time       Date       Cluster      Size\n";
  54.  
  55. /* display directory */
  56.  
  57. extern void dumpdir(unsigned char *buf, int sec_size)
  58. {
  59. int i;
  60.  
  61.    send('\n');
  62.    send('\n');
  63.    print(dir_header);                  /* print header */
  64.  
  65.    for (i = 0; i < sec_size; i+=32)    /* and each entry */
  66.    {
  67.       send('\n');
  68.       put(3,' ');
  69.       pdirent(buf+i);
  70.    }
  71.    send('\n');
  72. }
  73.  
  74. /* change dir command structure */
  75.  
  76. /* ...filename.txt...ttri...hh:mm:ss...mm/dd/yy...1234567...1234567 */
  77. struct fields {
  78.    int beg;             /* starting column */
  79.    int end;             /* ending column */
  80.    int (*inp)();        /* function to do the change */
  81. } field[] = {
  82.    4,7,  command,
  83.    9,16, text,
  84.    18,20,text,
  85.    24,28,attrib,
  86.    32,33,dostime,
  87.    43,44,dosdate,
  88. };
  89.  
  90. /*
  91.    NOTE: The above structure definition uses int (*inp)(); to define
  92.    a pointer to a function.  Because different functions are called,
  93.    each taking different arguments, the arguments in the definition
  94.    are left blank.  This works fine except for the first call to one
  95.    instance will result in the warning:
  96.  
  97.       'field' : no function prototype given
  98.  
  99.    I dont know how to get around this.
  100. */
  101.  
  102. /***
  103. *changedir() - edit directory entry(s) in sector buffer
  104. *
  105. *  ver 1.1  fixed =0 bug
  106. ****/
  107.  
  108. extern int changedir(unsigned char *buf,int sec_size)
  109. {
  110. int i,r,o;
  111. byte a,x;
  112. unsigned int *b;
  113. unsigned int c;
  114. unsigned int n;
  115. int p;            /* absolute position */
  116. int f;            /* field in  */
  117.  
  118.    getcursor(&a,&x);
  119.    send('\n');
  120.    send('\n');
  121.    put(6,' ');
  122.    print(dir_header);
  123.    i = r = 0;
  124.    for (;;)
  125.    {
  126.       f = 0;                     /* start off at command function */
  127.       p=field[f].beg;
  128.       send('\n');
  129.       pnlz(i+1,3,10);
  130.       put(6,' ');
  131.       o=i*32;
  132.       r=pdirent(buf+o);
  133. get:
  134.       setcursor(a,(byte)p);
  135.  
  136.       switch (f)
  137.       {
  138.          case 0:                                /* command */
  139.             c = (*field[f].inp)(r);
  140.             break;
  141.          case 1:                                /* file name */
  142.             c = (*field[f].inp)(8,buf+o);
  143.             break;
  144.          case 2:                                /* file extension */
  145.             c = (*field[f].inp)(3,buf+o+8);
  146.             break;
  147.          case 3:                                /* attribute */
  148.             c = (*field[f].inp)(buf+o+11);
  149.             break;
  150.          case 4:                                /* time */
  151.             b=(unsigned int *)(buf+o+0x16);
  152.             c = (*field[f].inp)(*b,b);
  153.             break;
  154.          case 5:                                /* date */
  155.             b=(unsigned int *)(buf+o+0x18);
  156.             c = (*field[f].inp)(*b,b);
  157.             break;
  158.          default:
  159.             break;
  160.       }
  161.  
  162.       /* deal with key returned from functions */
  163.  
  164.       if (c==RIGHT)
  165.          c='\t';
  166.       else if (c==SHTAB || c==CLEFT)
  167.          c=0x7f;
  168.       else if (c==LEFT)                         /* goto previous sub-field */
  169.       {
  170.          if (f > 0)                             /* if not in command field */
  171.             if (p > field[f].beg)
  172.                --p;
  173.             else                                /* if at first sub-field */
  174.                p=field[--f].beg;                /* goto previous field */
  175.       }
  176.       else if (c==CRIGHT)
  177.          c='\t';
  178.       else if (c==DOWN)
  179.          c='\r';
  180.       else if (c==UP)
  181.          c='\b';
  182.       c&=0xff;
  183.       if (c==0x7f)                              /* goto previoud field */
  184.       {
  185.          if (f>0)
  186.             p=field[--f].beg;
  187.       }
  188.       if (c=='\t')                              /* goto next field */
  189.       {
  190.          if (f<sizeof(field)/sizeof(struct fields)-1)
  191.             p=field[++f].beg;
  192.       }
  193.       if (c=='\r' || c==' ')                    /* goto next entry */
  194.       {
  195.          if (i==(sec_size/32)-1)
  196.          {
  197.             send('\n');
  198.             send('\n');
  199.             put(6,' ');
  200.             print(dir_header);
  201.             i=0;
  202.          }
  203.          else
  204.             i++;
  205.          continue;
  206.       }
  207.       if (c=='\b')                              /* goto previous entry */
  208.       {
  209.          if (i)
  210.             i--;
  211.          else
  212.          {
  213.             i=(sec_size/32)-1;
  214.             send('\n');
  215.             send('\n');
  216.             put(6,' ');
  217.             print(dir_header);
  218.          }
  219.          continue;
  220.       }
  221.       if (c=='=')                               /* goto selected entry */
  222.       {
  223.          conout(c);
  224.          if (getnum(sec_size/32,&n,10) > 0 && n > 0)
  225.             i = n-1;
  226.          continue;
  227.       }
  228.       if (c=='/' || c=='?')
  229.       {
  230.          print("\n\n\tCR/SP  next file");
  231.          print("\n\tBS     previous file");
  232.          print("\n\tTAB    next field");
  233.          print("\n\tSHTAB  previous field");
  234.          print("\n\t=n     goto file n");
  235.          print("\n\t.|ESC  exit\n");
  236.          continue;
  237.       }
  238.       if (c=='.' || c==ESC)
  239.          break;
  240.       goto get;
  241.    }
  242.    send('\n');
  243.    return(0);
  244. }
  245.  
  246. static int command(int c)
  247. {
  248. int i;
  249.  
  250.    i=conin();
  251.    if (c<1 && (i==RIGHT || i==TAB))
  252.       i=0;
  253.    return(i);
  254. }
  255.  
  256. /***
  257. *text() -- edit a text entry (filename/ext)
  258. *
  259. *  can enter ALL printable characters including '.' and ' '
  260. ****/
  261.  
  262. static int text(int len, unsigned char *buf)
  263. {
  264. int c;
  265. int i;
  266.  
  267.    for (i=0;;)
  268.    {
  269.       c=conin();
  270.       if (c==RIGHT)
  271.       {
  272.          if (i==len-1)
  273.             break;
  274.          curright();
  275.          ++i;
  276.          continue;
  277.       }
  278.       if (c==LEFT || c==BACKSP)
  279.       {
  280.          if (!i)
  281.             break;
  282.          --i;
  283.          curleft();
  284.          continue;
  285.       }
  286.       if (c==RETURN || c==TAB || c==SHTAB || c==DOWN || c==UP)
  287.          break;
  288.       if (c==ESCAPE)
  289.          return(0);
  290.       if (c>0x352f) continue;
  291.       c&=0xff;
  292.       if (isgraph(c) || isexten(c))
  293.       {
  294.          *(buf+i)=(char)c;
  295.          i++;
  296.          conout(c);
  297.          if (i==len)
  298.          {
  299.             c=RIGHT;
  300.             break;
  301.          }
  302.       }
  303.    }
  304.    return(c);
  305. }
  306.  
  307. /***
  308. *attrib() - toggle filename attributes, except for dir
  309. *
  310. ****/
  311.  
  312. static int attrib(unsigned char *buf)
  313. {
  314. int i;
  315. int b,c,p,d;
  316. byte isvol;
  317.  
  318.    /* 01234 */
  319.    /* RHSDA */
  320.  
  321.    isvol = (byte)(*buf&8);
  322.    p=0;
  323.  
  324.    for (;;)
  325.    {
  326.       i=conin();
  327.       if (i==RETURN || i==TAB || i==SHTAB || i==DOWN || i==UP)
  328.          break;
  329.       if (i==ESCAPE)
  330.       {
  331.          i=0;
  332.          break;
  333.       }
  334.       if (i==RIGHT)
  335.       {
  336.          if (p==4)      /* end */
  337.             break;
  338.          curright();
  339.          ++p;
  340.          continue;
  341.       }
  342.       if (i==LEFT || i==BACKSP)
  343.       {
  344.          if (p==0)
  345.             break;
  346.          --p;
  347.          curleft();
  348.          continue;
  349.       }
  350.  
  351.       if ( !isvol && p!=3 && (i&0xff)==' ')
  352.       {
  353.          if (p==0)
  354.          {
  355.             b=1;
  356.             d='R';
  357.          }
  358.          else if (p==1)
  359.          {
  360.             b=2;
  361.             d='H';
  362.          }
  363.          else if (p==2)
  364.          {
  365.             b=4;
  366.             d='S';
  367.          }
  368.          else if (p==4)
  369.          {
  370.             b=0x20;
  371.             d='A';
  372.          }
  373.          if (*buf&b)
  374.          {
  375.             c='_';
  376.             *buf&=~b;
  377.          }
  378.          else
  379.          {
  380.             c=d;
  381.             *buf|=b;
  382.          }
  383.          conout(c);
  384.          curleft();
  385.       }
  386.    }
  387.    return(i);
  388. }
  389.  
  390. static int dostime(unsigned int time, unsigned int *t)
  391. {
  392. int i;
  393. int h,m,s;
  394. byte r,x;
  395. int c,p;
  396.  
  397.    /* 01234567 */
  398.    /* hh:mm:ss */
  399.  
  400.    getcursor(&r,&x);
  401.    c=x;
  402.    p=c;
  403.    h=time>>11;
  404.    m=(time>>5)&0x3f;
  405.    s=time&0x1f;
  406.  
  407.    for (;;)
  408.    {
  409.       setcursor(r,(byte)p);
  410.       i=conin();
  411.  
  412.       if (i==TAB || i==RETURN || i==SHTAB || i==DOWN || i==UP)
  413.          return(i);
  414.       if (i==ESCAPE)
  415.       {
  416.          i=0;
  417.          break;
  418.       }
  419.  
  420.       if (i==LEFT || i==BACKSP)
  421.       {
  422.          if (p==c && i==LEFT)
  423.             return(i);
  424.          if (p==c && i==BACKSP)
  425.             continue;
  426.          if (p==c+3 || p==c+6)
  427.             p-=2;
  428.          else
  429.             p--;
  430.          continue;
  431.       }
  432. right:
  433.       if (i==RIGHT)
  434.       {
  435.          if (p==c+7)
  436.             return(i);
  437.          if (p==c+1 || p==c+4)
  438.             p+=2;
  439.          else
  440.             p++;
  441.          continue;
  442.       }
  443.       i&=0xff;
  444.       if (isdigit(i))
  445.       {
  446.          conout(i);
  447.          i=i-'0';
  448.          if (p==c)
  449.             h=(i*10)+(h%10);
  450.          else if (p==c+1)
  451.             h=i+((h/10)*10);
  452.          else if (p==c+3)
  453.             m=(i*10)+(m%10);
  454.          else if (p==c+4)
  455.             m=i+((m/10)*10);
  456.          else if (p==c+6)
  457.             s=(i*10)+(s%10);
  458.          else if (p==c+7)
  459.             s=i+((s/10)*10);
  460.          time=(h<<11)+(m<<5)+s;
  461.          *t=time;
  462.          i=RIGHT;
  463.          goto right;
  464.       }
  465.    }
  466.    return(i);
  467. }
  468.  
  469. /***
  470. *dosdate() - edit date field
  471. *
  472. *  ver   1.1   fixed right arrow at last number from wrapping
  473. ****/
  474.  
  475. static int dosdate(unsigned int date, unsigned int *buf)
  476. {
  477. int i;
  478. int m,d,y;
  479. byte r,x;
  480. int c,p;
  481.  
  482.    /* 01234567 */
  483.    /* mm/dd/yy */
  484.  
  485.    getcursor(&r,&x);
  486.    c=x;
  487.    p=c;
  488.    m=(date>>5)&0xf;
  489.    d=date&0x1f;
  490.    y=((date>>9)&0x7f)+80;
  491.  
  492.    for (;;)
  493.    {
  494.       setcursor(r,(byte)p);
  495.       i=conin();
  496.  
  497.       if (i==TAB || i==RETURN || i==SHTAB || i==DOWN || i==UP)
  498.          break;
  499.       if (i==ESCAPE)
  500.          return(0);
  501.       if (i==LEFT || i==BACKSP)
  502.       {
  503.          if (p==c && i==LEFT)
  504.             return(i);
  505.          if (p==c && i==BACKSP)
  506.             continue;
  507.          if (p==c+3 || p==c+6)
  508.             p-=2;
  509.          else
  510.             p--;
  511.          continue;
  512.       }
  513. right:
  514.       if (i==RIGHT)
  515.       {
  516.          if (p==c+7)
  517.             continue;
  518.          if (p==c+1 || p==c+4)
  519.             p+=2;
  520.          else
  521.             p++;
  522.          continue;
  523.       }
  524.       i&=0xff;
  525.       if (isdigit(i))
  526.       {
  527.          conout(i);
  528.          i=i-'0';
  529.          if (p==c)
  530.             m=(i*10)+(m%10);
  531.          else if (p==c+1)
  532.             m=i+((m/10)*10);
  533.          else if (p==c+3)
  534.             d=(i*10)+(d%10);
  535.          else if (p==c+4)
  536.             d=i+((d/10)*10);
  537.          else if (p==c+6)
  538.             y=(i*10)+(y%10);
  539.          else if (p==c+7)
  540.             y=i+((y/10)*10);
  541.          if (y>80)
  542.             y-=80;
  543.          else
  544.             y=0;
  545.          date=(y<<9)+(m<<5)+d;
  546.          y+=80;
  547.          *buf=date;
  548.          i=RIGHT;
  549.          goto right;
  550.       }
  551.    }
  552.    return(i);
  553. }
  554.  
  555. /***
  556. *pdirent() - print directory entry
  557. *
  558. * v1.1   removed superfluous pointer
  559. ****/
  560.  
  561. static int pdirent(unsigned char *buf)
  562. {
  563. int i,r;
  564. long *l;
  565. unsigned char c;
  566. unsigned char *a;
  567. unsigned int m;
  568. char *attr = "RHSvDA";
  569.  
  570.    r = 1;
  571.    a = buf+0xb;
  572.    if (*(buf) == 0)
  573.    {
  574.       print(" unused");
  575.       r = 0;
  576.    }
  577.    else
  578.    {
  579.       if (*(buf) == 0xE5)
  580.          r = -1;
  581.       for (i = 0; i < 8; i++)
  582.       {
  583.          c = *(buf+i);
  584.          if (isspace((int)c) || c==255 || !c || c==7 || c==8)
  585.             conout(' ');
  586.          else
  587.             conout(c);
  588.       }
  589.       conout('.');
  590.       for (; i < 11; i++)
  591.       {
  592.          c = *(buf+i);
  593.          if (isspace((int)c) || c==255 || !c || c==7 || c==8)
  594.             conout(' ');
  595.          else
  596.             conout(c);
  597.       }
  598.       put(3,' ');
  599.       if (*a&8)
  600.          print(" Vol ");
  601.       else
  602.       {
  603.          for (m = 1,i = 0; i < 6; m<<=1,i++)
  604.          {
  605.             if (i==3)      /* skip vol */
  606.                continue;
  607.             if (*a&m)
  608.                conout(*(attr+i));
  609.             else
  610.                conout('_');
  611.          }
  612.       }
  613.       put(3,' ');
  614.       distime((DosTime *)(buf+0x16));
  615.       put(3,' ');
  616.       disdate((DosDate *)(buf+0x18));
  617.       put(3,' ');
  618.       pnls(*(unsigned int *)(buf+0x1a),7,10);
  619.       if (!(*a&0x10))
  620.       {
  621.          put(3,' ');
  622.          l = (long *)(buf+0x1c);
  623.          plnls(*l,7,10);
  624.       }
  625.    }
  626.    return(r);
  627. }
  628.  
  629. static void distime(DosTime *dt)
  630. {
  631.    pnlz(dt->hours,2,10);
  632.    conout(':');
  633.    pnlz(dt->minutes,2,10);
  634.    conout(':');
  635.    pnlz(dt->seconds,2,10);
  636. }
  637.  
  638. static void disdate(DosDate *dd)
  639. {
  640.    pnlz(dd->month,2,10);
  641.    conout('/');
  642.    pnlz(dd->day,2,10);
  643.    conout('/');
  644.    pnlz(dd->year+80,2,10);
  645. }
  646.